#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<cre2.h>

// 宏定义
#define MAXNUM 1000

 // 查找亲近同学
int find_closest_classmate(int *, int, const char *, const char *);
void output(int *, int); // 输出结果

// 测试
int main()
{
    // 声明变量
    int mno;
    char like[27]; // 26个大写字符+'\0'
    char classmate[MAXNUM + 1];  // MAXNUM个同学+'\0'
    int sno[MAXNUM];

    mno = 1;
    strcpy(like, "ABC");
    strcpy(classmate, "BPTYHJKAMNBPHC");

    // 处理数据
    int n = find_closest_classmate(sno, mno, like, classmate);

    // 输出结果
    output(sno, n);

    return 0;
}

// 查找亲近同学
int find_closest_classmate(int *sno, int myno,
                           const char *like,
                           const char *classmate)
{
    int n = 0;
    // 正则对象指针
    cre2_regexp_t *rex;
    // 选项对象指针
    cre2_options_t *opt;
    cre2_string_t input;
    int c;
    int nmatch = 1;
    cre2_string_t match;

    // 构造正则表达式
    char *pat = (char*)malloc((strlen(like) + 4 + 1) * sizeof(char));
    if(pat == NULL)
    {
        printf("not enough memory!\n");
        exit(EXIT_FAILURE);
    }

    // 正则表达式(注意添加小括号分组)
    memset(pat, 0, (strlen(like) + 4 + 1) * sizeof(char));
    strcat(pat, "([");
    strcat(pat, like);
    strcat(pat, "])");

    // 待匹配对象
    input.data = classmate;
    input.length = strlen(classmate);

    // 创建选项对象
    opt = cre2_opt_new();
    // 设置选项(启用POSIX语法)
    cre2_opt_set_posix_syntax(opt, 1);

    // 编译正则表达式，构建正则对象
    rex = cre2_new(pat, strlen(pat), opt);
    if(cre2_error_code(rex))
    {
        exit(EXIT_FAILURE);
    }

    c = cre2_find_and_consume_re(rex, &input, &match, nmatch);
    while(c == 1)
    {
        // 只记录与自己学号不同的朋友(地址相减)
        if((match.data - classmate + 1) != myno)
        {
            sno[n] = match.data - classmate + 1;
            n++;
        }

        c = cre2_find_and_consume(pat, &input, &match, nmatch);
    }

    // 释放空间
    cre2_delete(rex);
    cre2_opt_delete(opt);
    free(pat);

    return n; // 返回找到的亲近同学总数
}

// 输出结果
void output(int *sno, int n)
{
    int i;

    if(n > 0)
    {
        for(i = 0; i < n - 1; i++)
        {
            printf("%d ", sno[i]);
        }
        printf("%d\n", sno[i]); // 避免最后输出多1个空格
    }
    else
    {
        printf("Lonely Xiao Ming\n");
    }
}
